#pragma once
#include <string>
#include <memory>
#include <amqpcpp.h>
#include <amqpcpp/libboostasio.h>
#include "net/core.h"
#include "service/request.h"

using std::string;
namespace libzq
{

	template<typename Protocol>
	class Boradcast :
		public RequestImpl
	{
	public:
		Boradcast(const char* method) :
			RequestImpl(method, 0)
		{

		}
		static void reg(const char* host)
		{
			static AMQP::LibBoostAsioHandler handler(CORE.ioservice());
			static AMQP::TcpConnection connection(&handler, AMQP::Address(host));
			Boradcast<Protocol>::channel = std::make_shared<AMQP::TcpChannel>(&connection);
			CORE.install_stop([]()
			{
				Boradcast<Protocol>::channel->close();
			});
		}
		Boradcast<Protocol>& boradcast(const char* exchange, const char* routing_key);
		Boradcast<Protocol>& exec(Protocol arg);
	private:
		static std::shared_ptr<AMQP::TcpChannel> channel;
		string _exchange;
		string _routing_key;
	};
	template<typename Protocol>
	std::shared_ptr<AMQP::TcpChannel> Boradcast<Protocol>::channel = nullptr;

	template<typename Protocol>
	Boradcast<Protocol> & Boradcast<Protocol>::boradcast(const char * exchange, const char * routing_key)
	{
		_exchange = exchange;
		_routing_key = routing_key;
		return *this;
	}

	template<typename Protocol>
	Boradcast<Protocol> & Boradcast<Protocol>::exec(Protocol arg)
	{
		if (Boradcast<Protocol>::channel)
		{
			arg.set_method(_method);
			string req_str = arg.dumps();
			MsgPacker msg(req_str, _msgid.c_str());
			Boradcast<Protocol>::channel->publish(_exchange, _routing_key, msg.pack_msg());
		}
		else
		{
			LOGE("Should call Boradcast::reg first!!!");
		}
		return *this;
	}
}